package com.todod.common.http;


import com.todod.common.constant.ApiConstants;
import com.todod.exception.CustomException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.*;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author gsh
 * @version 1.0
 * @date 2021/4/7 0007 09:57
 */
@Slf4j
public class HttpUtil {

    public static void main(String[] args) throws Exception {
        RequestData requestData = new RequestData();
        requestData.setUrl("https://www.fastmock.site/mock/73fb900ffd01cd7f6cbf459a89b7e860/fill_in/api/select4");

        ResponseData responseData = doGet(requestData);
        System.out.println(responseData);

//        RequestData requestData = new RequestData();
//        requestData.setUrl("http://114.115.144.31:8888/query_data/user/login");
//        requestData.setBody("{\"loginName\":\"admin\",\"password\":\"111111\"}");
//
//        Map<String, String> map = new HashMap<>();
//        map.put("Content-Type" , "application/json;charset=utf-8");
//        requestData.setHeaders(map);
//
//        ResponseData responseData = doPost(requestData);
//        System.out.println(responseData);
    }

    public static ResponseData req(RequestData requestData) throws IOException {
        if (ApiConstants.REQUEST_METHOD_GET.equalsIgnoreCase(requestData.getMethod())) {
            return doGet(requestData);
        } else if (ApiConstants.REQUEST_METHOD_POST.equalsIgnoreCase(requestData.getMethod())) {
            return doPost(requestData);
        } else if (ApiConstants.REQUEST_METHOD_PUT.equalsIgnoreCase(requestData.getMethod())) {
            return doPut(requestData);
        } else if (ApiConstants.REQUEST_METHOD_DELETE.equalsIgnoreCase(requestData.getMethod())) {
            return doDelete(requestData);
        } else {
            throw new CustomException("请求方法错误");
        }
    }

    /**
     * get
     *
     * @param requestData requestData
     * @return com.todod.dsb.api.manage.common.http.ResponseData
     * @author gsh
     * @date 2021/4/7 0007 14:46
     */
    public static ResponseData doGet(RequestData requestData) throws IOException {
        CloseableHttpClient httpclient = null;
        CloseableHttpResponse response = null;
        try {
            String url = buildUrl(requestData.getUrl(), requestData.getParams());

            HttpGet httpGet = new HttpGet(url);
            addTimeOut(httpGet, requestData.getTimeOut());
            addHeader(httpGet, requestData.getHeaders());

            httpclient = HttpClients.createDefault();
            response = httpclient.execute(httpGet);

            return ResponseData.createRespone(response);
        } finally {
            if (response != null) {
                response.close();
            }
            if (httpclient != null) {
                httpclient.close();
            }
        }
    }

    /**
     * post
     *
     * @param requestData
     * @return com.todod.dsb.api.manage.common.http.ResponseData
     * @author gsh
     * @date 2021/4/7 0007 15:05
     */
    public static ResponseData doPost(RequestData requestData) throws IOException {
        CloseableHttpClient httpclient = null;
        CloseableHttpResponse response = null;
        try {
            String url = buildUrl(requestData.getUrl(), requestData.getParams());

            HttpPost httppost = new HttpPost(url);
            addTimeOut(httppost, requestData.getTimeOut());
            addHeader(httppost, requestData.getHeaders());

            //设置发送的数据
            if (StringUtils.isNotBlank(requestData.getBody())) {
                StringEntity s = new StringEntity(requestData.getBody());
                httppost.setEntity(s);
            }

            httpclient = HttpClients.createDefault();
            response = httpclient.execute(httppost);

            return ResponseData.createRespone(response);
        } finally {
            if (response != null) {
                response.close();
            }
            if (httpclient != null) {
                httpclient.close();
            }
        }
    }

    /**
     * put
     *
     * @param requestData
     * @return com.todod.dsb.api.manage.common.http.ResponseData
     * @author gsh
     * @date 2021/4/7 0007 15:05
     */
    public static ResponseData doPut(RequestData requestData) throws IOException {
        CloseableHttpClient httpclient = null;
        CloseableHttpResponse response = null;
        try {
            String url = buildUrl(requestData.getUrl(), requestData.getParams());

            HttpPut httpPut = new HttpPut(url);
            addTimeOut(httpPut, requestData.getTimeOut());
            addHeader(httpPut, requestData.getHeaders());

            //设置发送的数据
            if (StringUtils.isNotBlank(requestData.getBody())) {
                StringEntity s = new StringEntity(requestData.getBody());
                httpPut.setEntity(s);
            }

            httpclient = HttpClients.createDefault();
            response = httpclient.execute(httpPut);

            return ResponseData.createRespone(response);
        } finally {
            if (response != null) {
                response.close();
            }
            if (httpclient != null) {
                httpclient.close();
            }
        }
    }

    /**
     * delete
     *
     * @param requestData
     * @return com.todod.dsb.api.manage.common.http.ResponseData
     * @author gsh
     * @date 2021/4/7 0007 15:05
     */
    public static ResponseData doDelete(RequestData requestData) throws IOException {
        CloseableHttpClient httpclient = null;
        CloseableHttpResponse response = null;
        try {
            String url = buildUrl(requestData.getUrl(), requestData.getParams());

            HttpDelete httpDelete = new HttpDelete(url);
            addTimeOut(httpDelete, requestData.getTimeOut());
            addHeader(httpDelete, requestData.getHeaders());

            httpclient = HttpClients.createDefault();
            response = httpclient.execute(httpDelete);

            return ResponseData.createRespone(response);
        } finally {
            if (response != null) {
                response.close();
            }
            if (httpclient != null) {
                httpclient.close();
            }
        }
    }

    /**
     * 构建url
     *
     * @param url    url
     * @param params 参数
     * @return java.lang.String
     * @author gsh
     * @date 2021/4/7 0007 11:55
     */
    private static String buildUrl(String url, List<Entity> params) {
        if (params == null || params.size() == 0) {
            return url;
        }
        String param = "";
        Map<String, String> map = new HashMap<>();
        for (Entity entity : params) {
            map.put(entity.getName(), entity.getValue());
        }
        for (String key : map.keySet()) {
            if (StringUtils.isNotBlank(key)) {
                param += "&" + key + "=" + map.get(key);
            }
        }

        if (url.contains("?")) {
            url = url + param;
        } else {
            param = param.substring(1, param.length());
            url = url + "?" + param;
        }
        log.info("url = " + url);
        return url;
    }

    /**
     * 添加请求超时设置
     *
     * @param httpRequestBase httpRequestBase
     * @param timeOut         超时时间 秒
     * @author gsh
     * @date 2021/4/7 0007 14:21
     */
    private static void addTimeOut(HttpRequestBase httpRequestBase, Integer timeOut) {
        if (timeOut != null && timeOut > 0) {
            timeOut *= 1000;
            RequestConfig requestConfig = RequestConfig.custom()
                    .setConnectTimeout(timeOut)
                    .setSocketTimeout(timeOut).build();
            httpRequestBase.setConfig(requestConfig);
        }
    }

    /**
     * 添加请求头
     *
     * @param httpRequestBase httpRequestBase
     * @param headerList      herder
     * @author gsh
     * @date 2021/4/7 0007 14:22
     */
    private static void addHeader(HttpRequestBase httpRequestBase, List<Entity> headerList) {
        if (headerList != null && headerList.size() > 0) {
            for (Entity entity : headerList) {
                if (StringUtils.isNotBlank(entity.getName())) {
                    httpRequestBase.setHeader(entity.getName(), entity.getValue());
                }
            }
        }
    }
}
